package pl.webapps.alarmme;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemLongClickListener;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.SimpleAdapter.ViewBinder;

public class ListViewMapper {
    private List<Map<String, Object>> mItemsList;
    private ListView mListView;
    private SimpleAdapter mAdapter;
    private Context mContext;
    private AlarmUtils mAlarmUtils;
    private Bitmap mBmpRed;
    private Bitmap mBmpGreen;
    private static final String ICON = "icon";
    private static final String CONTENT = "content";
    private static final String ACTIVE = "active";
    private static final String[] PARAM = { ICON, CONTENT };
    private static final String ACTIVE_ALARM_FLAG = "y";
    private static final String LOG_TAG = "AlarmMe.ListViewMapper";

    public ListViewMapper(ListView listView, Context context) {
        mContext = context;
        mItemsList = new ArrayList<Map<String, Object>>();
        mAlarmUtils = new AlarmUtils(mContext);
        mListView = listView;
        List<String> alarmsList = getSavedAlarms();
        String textString = mContext.getResources().getString(R.string.alarm_set_to) + " ";
        mBmpRed = BitmapFactory.decodeResource(mContext.getResources(), R.drawable.red);
        mBmpGreen = BitmapFactory.decodeResource(mContext.getResources(), R.drawable.green);
        if (alarmsList != null) {
            for (Iterator<String> iterator = alarmsList.iterator(); iterator.hasNext();) {
                String item = iterator.next();
                if (item.toLowerCase().contains(ACTIVE_ALARM_FLAG)) {
                    addItem(mItemsList, mBmpGreen, textString + item.substring(0, item.length() - 2), true);
                } else {
                    addItem(mItemsList, mBmpRed, textString + item.substring(0, item.length() - 2), false);
                }
            }
        }
        mAdapter = new SimpleAdapter(mContext, mItemsList, R.layout.list_icon_text_elem, PARAM, new int[] {
                R.id.list_image, R.id.list_content_text });
        mAdapter.setViewBinder(new MyViewBinder());
        mListView.setAdapter(mAdapter);
        mListView.setOnItemClickListener(new OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                clickOnAlarmAction(mItemsList.get(position));
            }
        });
        mListView.setOnItemLongClickListener(new OnItemLongClickListener() {
            @Override
            public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
                longClickOnAlarmAction(position);
                return true;
            }
        });
    }

    private void addItem(List<Map<String, Object>> data, Bitmap bitmap, String content, boolean isActive) {
        Map<String, Object> map = new HashMap<String, Object>();
        map.put(ICON, bitmap);
        map.put(CONTENT, content);
        map.put(ACTIVE, new Boolean(isActive));
        data.add(map);
    }

    private List<String> getSavedAlarms() {
        return PreferencesHandler.loadCurrentAlarms();
    }

    private boolean saveCurrentAlarms() {
        List<String> alarms = new ArrayList<String>();
        for (Iterator<Map<String, Object>> iterator = mItemsList.iterator(); iterator.hasNext();) {
            Map<String, Object> item = iterator.next();
            String timeText = (String) item.get(CONTENT);
            Boolean isActive = (Boolean) item.get(ACTIVE);
            String onlyTime = timeText.substring(timeText.lastIndexOf(":") - 2, timeText.lastIndexOf(":") + 3);
            String alarmToBeAdded = onlyTime + " " + (isActive.booleanValue() == true ? "Y" : "N");
            alarms.add(alarmToBeAdded);
        }
        return PreferencesHandler.saveCurrentAlarms(alarms);
    }

    public int addNewAlarm(int hour, int minute, boolean is24format) {
        if (mItemsList.size() > 9) {
            return AlarmUtils.ERR_ALARM_LIMIT_REACHED;
        } else {
            String timeToBeAdded = TimeUtils.formatTime(hour, minute, is24format);
            for (Iterator<Map<String, Object>> iterator = mItemsList.iterator(); iterator.hasNext();) {
                Map<String, Object> item = iterator.next();
                if (((String) item.get(CONTENT)).toLowerCase().contains(timeToBeAdded.toLowerCase())) {
                    return AlarmUtils.ERR_ALARM_EXISTS;
                }
            }
            String textString = mContext.getResources().getString(R.string.alarm_set_to) + " ";
            String content = textString + timeToBeAdded;
            visualTurnOffAllAlarms();
            addItem(mItemsList, mBmpGreen, content, true);
            mAlarmUtils.turnOnAlarm(content);
            saveCurrentAlarms();
            mAdapter.notifyDataSetChanged();
            return AlarmUtils.ALARM_ADDED_SUCCESSFULLY;
        }
    }

    private void longClickOnAlarmAction(final int alarmPositionOnList) {
        AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
        Resources r = mContext.getResources();
        String content = (String) mItemsList.get(alarmPositionOnList).get(CONTENT);
        builder.setTitle(content);
        CharSequence[] items = { r.getString(R.string.dialog_cancel_alarm), r.getString(R.string.dialog_back) };
        builder.setItems(items, new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int item) {
                if (item == 0) {
                    removeAlarm(alarmPositionOnList);
                }
            }
        });
        AlertDialog alert = builder.create();
        alert.show();
    }

    private void removeAlarm(int alarmPositionOnList) {
        Log.d(LOG_TAG, "removeAlarm");
        Map<String, Object> map = mItemsList.get(alarmPositionOnList);
        // String content = (String) map.get(CONTENT);
        Boolean active = (Boolean) map.get(ACTIVE);
        if (active.booleanValue()) {
            Log.d(LOG_TAG, "turnOffGlobalAlarm");
            mAlarmUtils.turnOffGlobalAlarm();
        } else {
            Log.d(LOG_TAG, "DO NOT turnOffGlobalAlarm");
        }
        mItemsList.remove(alarmPositionOnList);
        saveCurrentAlarms();
        mAdapter.notifyDataSetChanged();
    }

    private void clickOnAlarmAction(Map<String, Object> map) {
        changeAlarmActivity(map);
        mAdapter.notifyDataSetChanged();
    }

    private void changeAlarmActivity(Map<String, Object> map) {
        Boolean active = (Boolean) map.get(ACTIVE);
        map.remove(ACTIVE);
        map.remove(ICON);
        if (active.booleanValue()) {
            map.put(ICON, mBmpRed);
            mAlarmUtils.turnOffGlobalAlarm();
            // mAlarmUtils.turnOffAlarm((String) map.get(CONTENT));
        } else {
            visualTurnOffAllAlarms();
            map.put(ICON, mBmpGreen);
            mAlarmUtils.turnOnAlarm((String) map.get(CONTENT));
        }
        map.put(ACTIVE, new Boolean(!active.booleanValue()));
        saveCurrentAlarms();
    }

    private void visualTurnOffAllAlarms() {
        for (Iterator<Map<String, Object>> iterator = mItemsList.iterator(); iterator.hasNext();) {
            Map<String, Object> map = iterator.next();
            map.remove(ACTIVE);
            map.remove(ICON);
            map.put(ICON, mBmpRed);
            map.put(ACTIVE, new Boolean(false));
        }
    }
}

class MyViewBinder implements ViewBinder {
    @Override
    public boolean setViewValue(View view, Object data, String textRepresentation) {
        if ((view instanceof ImageView) && (data instanceof Bitmap)) {
            ImageView iv = (ImageView) view;
            Bitmap bm = (Bitmap) data;
            iv.setImageBitmap(bm);
            return true;
        }
        return false;
    }
}
